package top.lshaci.framework.file.oss.config;

import com.alibaba.alicloud.context.AliCloudProperties;
import com.alibaba.alicloud.context.oss.OssProperties;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSEncryptionClient;
import com.aliyun.oss.OSSEncryptionClientBuilder;
import com.aliyun.oss.crypto.SimpleRSAEncryptionMaterials;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.lshaci.framework.file.oss.properties.FrameworkOssProperties;
import top.lshaci.framework.file.oss.service.OssFileOperateService;
import top.lshaci.framework.file.oss.service.impl.OssFileOperateServiceImpl;
import top.lshaci.framework.file.properties.FrameworkFileProperties;

import java.security.KeyPair;
import java.util.Optional;

/**
 * FrameworkOssConfig
 *
 * @author lshaci
 * @since 1.0.9
 */
@Slf4j
@Configuration
@AllArgsConstructor
@ConditionalOnProperty(value = "framework.oss.enabled", matchIfMissing = true)
@EnableConfigurationProperties({FrameworkFileProperties.class, FrameworkOssProperties.class})
public class FrameworkOssConfig {

    private final OssProperties ossProperties;

    private final AliCloudProperties aliCloudProperties;

    private final FrameworkOssProperties frameworkOssProperties;

    private final FrameworkFileProperties frameworkFileProperties;

    /**
     * 配置 aliyun oss encryption 客户端
     *
     * @return aliyun oss encryption 客户端
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty("framework.oss.encryption.enabled")
    public OSSEncryptionClient ossEncryptionClient() {
        log.debug("Config oss encryption client...");

        String endpoint = ossProperties.getEndpoint();
        String accessKeyId = aliCloudProperties.getAccessKey();
        String accessKeySecret = aliCloudProperties.getSecretKey();
        KeyPair keyPair = frameworkOssProperties.getEncryption().keyPair();

        SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair);
        return new OSSEncryptionClientBuilder().build(endpoint, accessKeyId, accessKeySecret, encryptionMaterials);
    }

    /**
     * 配置文件操作业务类
     *
     * @param ossClient           oss client
     * @param ossEncryptionClient oss encryption client
     * @return 文件操作业务类
     */
    @Bean
    public OssFileOperateService ossFileOperateService(
            @Autowired(required = false) @Qualifier("ossClient") OSS ossClient,
            @Autowired(required = false) @Qualifier("ossEncryptionClient") OSS ossEncryptionClient
    ) {
        final OSS oss = Optional.ofNullable(ossEncryptionClient).orElse(ossClient);
        assert oss != null;
        log.debug("Config oss file upload service, OSS client: {}, Max file size: {}...", oss.getClass(), frameworkFileProperties.getMaxSize());
        return new OssFileOperateServiceImpl(oss, frameworkOssProperties.getBucket(), frameworkFileProperties.getMaxSize());
    }

}
